package com.intelligent.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.intelligent.mapper.CustomerReconciliationMapper;
import com.intelligent.pojo.CustomerManagement;
import com.intelligent.pojo.CustomerReconciliation;
import com.intelligent.pojo.ReceiptOrder;
import com.intelligent.pojo.SalesOrders;
import com.intelligent.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;


@Service
public class CustomerReconciliationServiceImpl extends ServiceImpl<CustomerReconciliationMapper, CustomerReconciliation>
    implements CustomerReconciliationService{

    @Autowired
    private SalesOrdersService salesOrdersService;

    @Autowired
    private ReceiptOrderService receiptOrderService;

    @Autowired
    private CustomerManagementService customerManagementService;

    @Autowired
    private CustomerReconciliationDetailService reconciliationDetailService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public CustomerReconciliation createReconciliation(CustomerReconciliation reconciliation) {
        // 验证客户是否存在
        CustomerManagement customer = customerManagementService.getById(reconciliation.getCustomerId());
        if (customer == null) {
            throw new RuntimeException("客户不存在");
        }

        // 生成对账单号：KHDZ+年份+月份+日期+4位数自增ID
        String yearMonthDay = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));

        // 先保存获取自增ID
        boolean saved = this.save(reconciliation);
        if (!saved) {
            throw new RuntimeException("保存对账单失败");
        }

        // 生成对账单号
        String recoCode = "KHDZ" + yearMonthDay + String.format("%04d", reconciliation.getRecoId());
        reconciliation.setRecoCode(recoCode);

        // 计算该周期内的各项金额
        amounts(reconciliation);

        // 更新对账单
        boolean updated = this.updateById(reconciliation);
        if (!updated) {
            throw new RuntimeException("更新对账单失败");
        }

        // 根据对账单生成明细
        reconciliationDetailService.generateFromReconciliation(reconciliation.getRecoId());

        return reconciliation;
    }

    @Override
    public Page<CustomerReconciliation> pageReconciliation(Page<CustomerReconciliation> page, String recoCode, Long customerId, Integer status, Date createDate) {
        LambdaQueryWrapper<CustomerReconciliation> wrapper = new LambdaQueryWrapper<>();

        // 根据对账单号搜索
        if (recoCode != null && !recoCode.trim().isEmpty()) {
            wrapper.like(CustomerReconciliation::getRecoCode, recoCode.trim());
        }

        // 根据客户ID搜索
        if (customerId != null) {
            wrapper.eq(CustomerReconciliation::getCustomerId, customerId);
        }

        // 根据状态搜索
        if (status != null) {
            wrapper.eq(CustomerReconciliation::getStatus, status);
        }

        // 根据创建日期搜索
        if (createDate != null) {
            wrapper.eq(CustomerReconciliation::getCreateDate, createDate);
        }

        wrapper.orderByDesc(CustomerReconciliation::getRecoId);
        return this.page(page, wrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateReconciliationStatus(Long id, Integer status) {
        CustomerReconciliation reconciliation = this.getById(id);
        if (reconciliation == null) {
            throw new RuntimeException("未找到对账单");
        }

        // 更新状态：0：待对账；1：部分对账；2：全部对账
        reconciliation.setStatus(status);

        return this.updateById(reconciliation);
    }

    @Override
    public void amounts(CustomerReconciliation reconciliation) {
        Long customerId = reconciliation.getCustomerId();
        Date startDate = reconciliation.getCreateDate();
        Date endDate = reconciliation.getEndDate();

        // 验证客户是否存在
        CustomerManagement customer = customerManagementService.getById(customerId);
        if (customer == null) {
            throw new RuntimeException("客户不存在，无法计算金额");
        }

        System.out.println("=== 开始计算金额 ===");
        System.out.println("客户ID: " + customerId + ", 客户名称: " + customer.getCustomerName());
        System.out.println("开始日期: " + startDate + ", 结束日期: " + endDate);

        // 计算应收（关联sales_orders表的订单总金额）
        LambdaQueryWrapper<SalesOrders> salesWrapper = new LambdaQueryWrapper<>();
        salesWrapper.eq(SalesOrders::getCustomerId, customerId)
                   .between(SalesOrders::getOrderDate, startDate, endDate);
        List<SalesOrders> salesOrders = salesOrdersService.list(salesWrapper);

        System.out.println("查询到的销售订单数量: " + salesOrders.size());
        if (!salesOrders.isEmpty()) {
            System.out.println("销售订单详情:");
            salesOrders.forEach(order -> {
                System.out.println("  订单ID: " + order.getId() +
                                 ", 订单号: " + order.getOrderNo() +
                                 ", 订单日期: " + order.getOrderDate() +
                                 ", 订单金额: " + order.getOrderAmount());
            });
        }

        BigDecimal currentReceivable = salesOrders.stream()
                .map(SalesOrders::getOrderAmount)
                .filter(amount -> amount != null)
                .reduce(BigDecimal.ZERO, BigDecimal::add);

        // 计算本期已收（关联receipt_order表的收款总金额）
        LambdaQueryWrapper<ReceiptOrder> receiptWrapper = new LambdaQueryWrapper<>();
        receiptWrapper.eq(ReceiptOrder::getCustomerId, customerId)
                     .between(ReceiptOrder::getCreationDate, startDate, endDate);
        List<ReceiptOrder> receiptOrders = receiptOrderService.list(receiptWrapper);

        System.out.println("查询到的收款单数量: " + receiptOrders.size());
        if (!receiptOrders.isEmpty()) {
            System.out.println("收款单详情:");
            receiptOrders.forEach(receipt -> {
                System.out.println("  收款单ID: " + receipt.getId() +
                                 ", 收款单号: " + receipt.getReceiptOrderNo() +
                                 ", 创建日期: " + receipt.getCreationDate() +
                                 ", 已核销金额: " + receipt.getWrittenOffAmount());
            });
        }

        BigDecimal currentReceived = receiptOrders.stream()
                .map(ReceiptOrder::getWrittenOffAmount)
                .filter(amount -> amount != null)
                .reduce(BigDecimal.ZERO, BigDecimal::add);

        // 计算本期待收（应收-已收）
        BigDecimal currentToReceive = currentReceivable.subtract(currentReceived);

        // 设置计算结果
        reconciliation.setCurrentReceivable(currentReceivable);
        reconciliation.setCurrentReceived(currentReceived);
        reconciliation.setCurrentToReceive(currentToReceive);

        System.out.println("=== 金额计算完成 ===");
        System.out.println("本期应收: " + currentReceivable);
        System.out.println("本期已收: " + currentReceived);
        System.out.println("本期待收: " + currentToReceive);
        System.out.println("==================");
    }
}
